-- UISelectTarget
-- Create by zouyb
-- 魔法释放时选择目标怪物

-- UISelectTarget继承自Layer
UISelectTarget = class("UISelectTarget", function()
    return cc.Layer:create();
end);

local instance = nil;

function UISelectTarget.getInstance()
    if instance == nil then
        instance = UISelectTarget.new();
    end

    return instance;
end

function UISelectTarget.create(classId)
    return UISelectTarget.new(classId);
end

function UISelectTarget:ctor(classId)
    -- 初始化
    self:setName("UISelectTarget");

    self:setLocalZOrder(UIMgr.TOP_MENU_ZORDER + 1);

    local node = cc.CSLoader:createNode("layout/spell/SpellSelectTarget.csb");
    self:addChild(node);
    self.node = node;
    local CT = node:getChildByName("CT");
    local CT2 = node:getChildByName("CT2");

    self.classId = classId;

    -- 注册事件处理回调函数
    self:registerEventCallback();

    self.CT = CT;
    self.CT2 = CT2;

    -- 初始化
    self:initView();

    self:showMask();

    -- 适配
    self:resize(node);

    -- 注册点击事件
    self:registerTouchEvent(node);
end

function UISelectTarget:initView()

    local spellInfo = SpellM.query(self.classId);

    -- 处于变身状态，创建变身状态的模型，否则创建普通模型
    local shapeId = ShapeChangeM.getShapeChangeId();
    if type(shapeId) == "number" and shapeId ~= -1 then
        -- 获取当前的出战宠物
        local pet = ME.user:getActivePet();
        local userPetId = pet.classId;

        self:createShapeChangeModel(shapeId);
    else
        -- 创建英雄模型
        self:createHeroModel();
    end

    -- 设置魔法效果
    local effect = findChildByName(self.node, "CT2/des");
    local skillId = SpellM.query(self.classId, "cast_skill_id");
    local effectText = SkillM.getSkillDesc(skillId, false, "append");
    effectText = string.gsub(effectText, "%[blue]", "[light_green]");
    TextStyleM.setTextStyle(effect, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_BEIGE);
    applyString(effect, effectText);

    -- 设置魔法名字及施放目标
    local name = findChildByName(self.node, "CT/name");
    local nameText = ItemM.query(self.classId, "name");

    local skillId = SpellM.query(self.classId, "cast_skill_id");
    local targetType = SkillM.query(skillId, "target");
    if targetType == ATTACKER then
        -- 对自身施放
        nameText = nameText .. getLocStr("no_select_target");
    elseif targetType == DEFENSER then
        -- 对敌方施放
        -- 主动技能，选择目标
        nameText = nameText .. getLocStr("select_target");
    else
        cclog("卷轴技能target类型不支持，请检查配置")
    end
    self.targetType = targetType;
    TextStyleM.setTextStyle(name, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_BEIGE);
    name:setString(nameText);

    -- 设置施法消耗
    local countAir = findChildByName(self.node, "CT/lanping/cost");
    TextStyleM.setTextStyle(countAir, TextStyleM.TEXT_SIZE_MIDDLE2, TextStyleM.TEXT_COLOR_WHITE, true, -4);
    countAir:setString(tostring(SpellM.calcSpellCost(self.classId)));

    -- 设置魔法值
    local curMp = ME.user:getMp();
    local curMpLabel = findChildByName(self.node, "CT/lanping/max")
    TextStyleM.setTextStyle(curMpLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_WHITE, true, -4);
    curMpLabel:setString("/" .. curMp);
end

-- 创建英雄模型
function UISelectTarget:createHeroModel()
    local headImg   = findChildByName(self.node, "CT/head_icon");
    local modelNode = findChildByName(self.node, "CT/model_node");

    -- 获取当前出战英雄
    local pet = ME.user:getActivePet();
    local classId = pet.classId;
    local petInfo = PetM.queryModel(pet:getModelId());

    local iconPath = getHeroIconPath(pet:getIcon());
    modelNode:removeAllChildren();
    createHeroModel(pet:getModelId(), headImg, modelNode, petInfo["model_scale"], iconPath);
end

-- 创建变身后的英雄模型
function UISelectTarget:createShapeChangeModel(shapeId)
    local headImg   = findChildByName(self.node, "CT/head_icon");
    local modelNode = findChildByName(self.node, "CT/model_node");

    -- 查询变身信息
    local shapeInfo = ShapeChangeM.query(shapeId);

    -- 获取当前出战英雄
    local iconPath = getHeroLargeIconPath(shapeInfo["icon"]);
    local animation = shapeInfo["animation"];
    modelNode:removeAllChildren();
    createShapeChangeMode(shapeId, headImg, animation, modelNode, shapeInfo["model_scale"], iconPath);
end

-- 注册点击事件
function UISelectTarget:registerTouchEvent(node)
    -- 注册返回按钮点击事件
    local btnBack = findChildByName(node, "BT/btn_back");
    local function onBackClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            -- 关闭当前界面
            UIMgr.getCurrentScene():removeFormByName("UISelectTarget");
        end
    end
    AddBackEventHandler(self, btnBack, onBackClick);
    TextStyleM.setTextStyle(btnBack, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnBack:setTitleText(getLocStr("btn_text_back"));
end

function UISelectTarget:spellNoTarget()
    self:noTargetSpell();

    -- 关闭当前界面
    UIMgr.getCurrentScene():removeFormByName("UISelectTarget");
end

function UISelectTarget:noTargetSpell()
    if self.targetType == ATTACKER then
        if SpellM.canUseSpell(self.classId, -1) then
            local function callback(classId)
                -- 被动技能，不需要选择目标
                DungeonActionM.go("use_spell", -1, classId);
                EventMgr.fire(event.PLAYER_MOVE, -1);
            end
            self:tryUseSpell(self.classId, callback);
        end
    end
end

-- 注册事件处理回调函数
function UISelectTarget:registerEventCallback()

    EventMgr.register("UISelectTarget", event.TARGET_SELECTED, function(pos)
        local openMonsterGrids = UIDungeonMgr:getCurLevel():getOpenMonsterGrids();
        for i = 1, #openMonsterGrids do
            print(openMonsterGrids[i].index)
            if openMonsterGrids[i].index == pos then
                if self.targetType ~= ATTACKER then
                    -- 使用卷轴
                    DungeonActionM.go("use_spell", pos, self.classId);
                end

                EventMgr.fire(event.PLAYER_MOVE, pos);
                break;
            end
        end

        if not UIMgr.getCurrentScene():isOpen("UISelectTarget") then
            -- 如果界面已经被关闭，不做任何处理
            return;
        end

        self:noTargetSpell();

        self:hideMask();

        -- 关闭当前界面
        UIMgr.getCurrentScene():removeFormByName("UISelectTarget");
    end);

    -- 界面析构后，需要清理下
    self:registerScriptHandler(function(ev)
        if ev == "exit" then
            cclog("UISelectTarget 界面析构清理");
            EventMgr.removeAll("UISelectTarget");

            if not UIDungeonMgr:getCurLevel() then
                return;
            end

            self:hideMask();

            -- 显示地牢的上下菜单
            UIDungeonMgr:getCurLevel():showTop();
            UIDungeonMgr:getCurLevel():showMenu();
        elseif ev == "enter" then
            if not UIDungeonMgr:getCurLevel() then
                return;
            end
            -- 隐藏地牢的上下菜单
            UIDungeonMgr:getCurLevel():hideTop();
            UIDungeonMgr:getCurLevel():hideMenu();
        end
    end);
end

-- 适配
function UISelectTarget:resize(node)
    local w = AlignM.frameSize.width;
    local h = AlignM.frameSize.height;

    local scaleX = w / DESIGN_WIDTH;
    local scaleY = h / DESIGN_HEIGHT;

    -- CT底部居中并缩放至合适大小
    AlignM.alignToBottomCenter(node, "CT");

    -- CT2顶部居中并缩放至合适大小
    AlignM.alignToTopCenter(node, "CT2");

    -- 蒙版需要拉伸至正常大小
    local CT = findChildByName(node, "CT");
    local CT2 = findChildByName(node, "CT2");
    local bg1 = findChildByName(node, "CT/bg1");
    local bg2 = findChildByName(node, "CT2/bg2");
    bg1:setScale(scaleX / CT:getScale(), scaleY / CT:getScale());
    bg2:setScale(scaleX / CT2:getScale(), scaleY / CT:getScale());

    -- BT置于底部并缩放至合适大小
    AlignM.alignToBottomCenter(node, "BT");
end

-- 显示蒙版
function UISelectTarget:showMask()
    showTargetSelectMask(self.targetType);
end

-- 隐藏蒙版
function UISelectTarget:hideMask()
    hideTargetSelectMask();
end

-- 使用卷轴之前先播放特殊效果
function UISelectTarget:tryUseSpell(classId, callback)
    if classId == 4005 then
        -- 使用大地之门之前播放特殊光效
        require "game/ui/form/spell/UIEarthPortalEffect";
        local uiForm = UIEarthPortalEffect.create(classId, callback);
        UIMgr.getCurrentScene():addForm(uiForm);
    elseif classId == 4035 then
        -- 使用时间停止之前播放特殊光效
        if UIDungeonMgr:getCurLevel().isTimeCeasing then
            alert(getLocStr("time_ceasing_use_hint"));
            return;
        end

        local effect;

        -- 光效播放父节点
        local effectParent = UIDungeonMgr:getCurLevel():getEffectParent();
        local _, effect = playEffect(effectParent, 35, 320, 480);

        if UIDungeonMgr:getCurLevel().timeCeaseEffect then
            UIDungeonMgr:getCurLevel().timeCeaseEffect:removeFromParent();
        end

        UIDungeonMgr:getCurLevel().timeCeaseEffect = effect;

        -- 倒计时
        local textLabel = ccui.Text:create();
        TextStyleM.setTextStyle(textLabel, TextStyleM.TEXT_SIZE_LARGE3, TextStyleM.TEXT_COLOR_WHITE);
        UIDungeonMgr:getCurLevel().timeCeaseLabel = textLabel;
        textLabel:setPosition(320, 480);
        effectParent:addChild(textLabel);
        textLabel:setOpacity(150);

        local function onFinish()
            UIDungeonMgr:getCurLevel().timeCeaseEffect.action:pause();
            if callback then
                performWithDelay(UIMgr.getCurrentScene(), function() callback(classId); end, 0.01);
            end
        end

        -- 等待动画播放完毕，中间玩家无法进行其他操作
        wait(2.66, onFinish);
    else
        callback(classId);
    end
end
